package jscinttools.scint.coincidence;

//import jscinttools.scint.coincidence.CoincidenceProbability;
import static jscinttools.utilities.aidautilities.AidaFactories.*;
import java.lang.Math;
import hep.aida.IFunction;

/**
 *  Description of the Class
 *
 *@author     Marc-Antoine Verdier
 *@created    20 avril 2011
 */
public class MultiCompCoincProba
{
	/**
	 *  Description of the Method
	 *
	 *@param  ly      Description of the Parameter
	 *@param  tau     Description of the Parameter
	 *@param  tcoinc  Description of the Parameter
	 *@param  m       Description of the Parameter
	 *@param  n       Description of the Parameter
	 *@return         Description of the Return Value
	 */
	public static double coincProba(double[] ly, double[] tau, double tcoinc, double m, double n)
	{
		return (1 - Math.pow(sumi(ly, tau, tcoinc) + 2 * sumij(ly, tau, tcoinc), (m * n)));
	}


	/**
	 *  Description of the Method
	 *
	 *@param  ly      Description of the Parameter
	 *@param  tau     Description of the Parameter
	 *@param  tcoinc  Description of the Parameter
	 *@return         Description of the Return Value
	 */
	public static IFunction photonEfficiency(double[] ly, double[] tau, double tcoinc)
	{
		return photonEfficiencyFunc(ly, tau, tcoinc, "*1.0");
	}


	/**
	 *  Description of the Method
	 *
	 *@param  ly      Description of the Parameter
	 *@param  tau     Description of the Parameter
	 *@param  tcoinc  Description of the Parameter
	 *@return         Description of the Return Value
	 */
	public static IFunction sumPhotonEfficiency(double[] ly, double[] tau, double tcoinc)
	{
		return photonEfficiencyFunc(ly, tau, tcoinc, "*0.5");
	}


	private static IFunction photonEfficiencyFunc(double[] ly, double[] tau, double tcoinc, String n)
	{
		String funcDef = "1-pow(sumi+2*sumij,pow(x[0]" + n + ",2))";
		String funcName = "Coincidence Efficiency";
		String param0 = "sumi";
		String param1 = "sumij";
		IFunction func = FUNCTION_FACTORY.createFunctionFromScript(funcName, 1, funcDef, param0 + "," + param1, funcName);
		func.setParameter(param0, sumi(ly, tau, tcoinc));
		func.setParameter(param1, sumij(ly, tau, tcoinc));
		return func;
	}


	/**
	 *  Description of the Method
	 *
	 *@param  ly      Description of the Parameter
	 *@param  tau     Description of the Parameter
	 *@param  tcoinc  Description of the Parameter
	 *@return         Description of the Return Value
	 */
	private static double sumi(double[] ly, double[] tau, double tcoinc)
	{
		double s = 0;
		for (int i = 0; i < ly.length; i++)
		{
			s += Math.pow(ly[i], 2) * Math.exp(-1.0 * tcoinc / tau[i]);
		}
		return s;
	}


	/**
	 *  Description of the Method
	 *
	 *@param  ly      Description of the Parameter
	 *@param  tau     Description of the Parameter
	 *@param  tcoinc  Description of the Parameter
	 *@return         Description of the Return Value
	 */
	private static double sumij(double[] ly, double[] tau, double tcoinc)
	{
		double s = 0;
		for (int i = 0; i < ly.length; i++)
		{
			for (int j = 0; j < ly.length; j++)
			{
				if (i != j)
					s += ly[i] * ly[j] * tau[j] / (tau[i] + tau[j]) * Math.exp(-1.0 * tcoinc / tau[j]);
			}
		}
		return s;
	}
}

